'use strict';

const path = require('path')
const fs = require('fs')
const shortid = require('shortid')
const axios = require('axios')
const url = require('url')
const app = require('../../server/server')
const { origin } = require('../../server/wechat/config')
module.exports = function(UserModel) {

  UserModel.observe('loaded', function (ctx, next) {

    if (!ctx.isNewInstance) {
      if (ctx.data && ctx.data.avatar) {
        ctx.data.avatar = url.resolve(origin, ctx.data.avatar)
      }
    }

    next()
  })

  // Note
  // headimgurl (relative path)
  // openid 普通用户的标识，对当前公众号唯一
  UserModel.login = function(params) {
    const { openid, headimgurl, avatar, nickname, subscribe_time } = params
    return UserModel
      .findOrCreate(
        { where: { openid: openid } },
        { openid, avatar, headimgurl, nickname, subscribe_time }
      )
      .then(user => {
        console.log('Login function', user)
        return user
      })
  }

  UserModel.createUser = function(user) {
    return saveAvatar(user.headimgurl)
      .then(filename => UserModel.create(Object.assign({}, user, { avatar: filename })))
  }

  function saveAvatar (url) {
    return axios({
      method: 'GET',
      url: url,
      responseType:'stream'
    })
    .then(response =>
      new Promise((resolve, reject) => {
        const rootPath = '/client/temp'
        const filename = shortid.generate() + '.png'
        const fStream = fs.createWriteStream(path.join(__dirname, '../..', rootPath, filename))

        fStream.on('finish', () => {
          console.log('download finish')
          resolve(path.join('temp', filename))
        })

        fStream.on('error', (err) => {
          reject(err)
        })

        response.data.pipe(fStream)
      })
    )
  }

  UserModel.saveAvatar = saveAvatar

  UserModel.getBoard = function(openid) {
    const Match = app.models.Match

    let gameSum = 0
    let huSum = 0, paoSum = 0, tingSum = 0
    let huRatio = 0, paoRatio = 0, tingRatio = 0
    let maxTimes = 0

    return UserModel
      .findOne({ where: { openid } })
      .then(user => user ? user : Promise.reject(null))
      .then(user => Match.findByUserid(user.id).then(matches => [ matches, user ]))
      .then(([ matches, user ]) => {
        matches.forEach(match =>
          match.__data.games.forEach(game => {
            gameSum += 1
            let hasTing = false
            let beichajiaoAction = null
            game._actions.forEach( action => {
              // 胡牌
              if (action.type === '胡' && String(action.owner.id) === String(user.id)) {
                huSum += 1
                hasTing = true
                maxTimes = Math.max(action.times, maxTimes)
              }

              // 点炮
              if (action.type === '胡' && !!action.targets.find(target => String(target.id) === String(user.id) )) {
                paoSum += 1
              }

              // 听牌 (没被查叫，targets里没有)
              // 1) 胡  => 自己胡了
              // 2）查叫，没被查  =>
              //    》胡了；
              //    》查叫，自己发起查叫
              // 3) 没有查叫 => 三家胡了；打完牌各自有叫

              // 自己发起查叫
              if (!hasTing && action.type === '查叫' && String(action.owner.id) === String(user.id)) {
                hasTing = true
              }

              // 查叫, owner不是自己
              if (!hasTing && action.type === '查叫' && String(action.owner.id) !== String(user.id)) {
                beichajiaoAction = action
              }
            })

            if (!hasTing) {
              // 没有被查叫
              if (!beichajiaoAction) {
                hasTing = true
              } else if (!beichajiaoAction.targets.find(tage => String(target.id) === String(user.id))){
                // 被查叫，但不包括自己
                hasTing = true
              }
            }

            tingSum += hasTing ? 1 : 0
          })
        )

        huRatio = gameSum ? huSum / gameSum : 0
        paoRatio = gameSum ? paoSum / gameSum : 0
        tingRatio = gameSum ? tingSum / gameSum : 0

        return { huRatio, paoRatio, tingRatio, maxTimes }
      })
      .catch(err => {
        console.log(err)
        return null
      })
  }

};
